package langnstats.project.ParserTools;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import edu.stanford.nlp.ling.HasWord;
import edu.stanford.nlp.ling.Sentence;
import edu.stanford.nlp.ling.Word;
import edu.stanford.nlp.parser.lexparser.*;
import edu.stanford.nlp.process.DocumentPreprocessor;
import edu.stanford.nlp.process.WordToTaggedWordProcessor;
import edu.stanford.nlp.trees.LabeledScoredTreeFactory;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TreeFactory;

public class StanfordParserHandel {

	String sent = "";
	LexicalizedParser parser;
	WordToTaggedWordProcessor wttwp;

	public void initializeParser(){

		parser = new LexicalizedParser("data/englishPCFG.ser.gz");
		parser.setOptionFlags(new String[]{"-forceTags"});
		wttwp = new WordToTaggedWordProcessor('/');		
		System.out.println("Parser is initialized...");

	}

//	This function gets a word, and returns the feature for that.
	public int getHistoryLengthFeature (){
		return sent.split("  *").length;
	}

	public String getParseFeature (String word){

		String feature;
		boolean flag=false; 

		if (word.equals("<COMMA>") || word.equals("<PERIOD>")){
			flag = true;
			word = word.replaceAll("<COMMA>",",").replaceAll("<COLON>",":").replaceAll("<PERIOD>",".").replaceAll("<RIGHTPAR>",")").replaceAll("<LEFTPAR>","(");
			sent += " "+word;
		}
		else
			sent += " x/"+word;

		if (sent.split("  *").length>5){ flag =true;}
		String parseLine = ParseInLine(sent+"\n");

		parseLine = parseLine.replaceAll("\\\\","");
		parseLine = parseLine.replaceAll(" \\\\x ", " ( x ) ");
		parseLine = parseLine.replaceFirst(" \\. \\) ", " ( x ) ) ");
		parseLine = parseLine.replaceAll(" , \\) ", " ( x ) ");
		parseLine = parseLine.replaceAll(" <LEFTPAR> ", " ( <LEFTPAR> ) ");
		parseLine = parseLine.replaceAll(" <RIGHTPAR> ", " ( <RIGHTPAR> ) ");
		parseLine = parseLine.replaceAll(" : \\) ", " ( x ) ");

		feature = ParseTree.getFeature(parseLine);

		if (flag || word.equals("<COMMA>") || word.equals("<PERIOD>")){
			sent = "";
		}

		return feature;
	}

	public Tree apply(String in) throws Exception {
		DocumentPreprocessor dp = new DocumentPreprocessor(parser.getOp().tlpParams.treebankLanguagePack().getTokenizerFactory());
		List<HasWord> lst = wttwp.process( (List<HasWord>)dp.getSentencesFromText(new StringReader(in)).get(0));
		try {
			if (parser.parse(lst)) {
				return parser.getBestParse();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		TreeFactory lstf = new LabeledScoredTreeFactory();
		List<Tree> lst2 = new ArrayList<Tree>();
		for (Object obj : lst) {
			String s = obj.toString();
			Tree t = lstf.newLeaf(s);
			Tree t2 = lstf.newTreeNode("X", Collections.singletonList(t));
			lst2.add(t2);
		}
		return lstf.newTreeNode("X", lst2);
	}

	public String ParseInLine (String sent){
		try {
			apply(sent);
		} catch (Exception e) {
			System.out.println("problem loading the sentence.");
			e.printStackTrace();
		}
		Tree parse = (Tree) parser.getBestPCFGParse();
		String treeString = parse.pennString();
		treeString = treeString.replaceAll("\n", "").replaceAll("\r","").replaceAll("\t","").replaceAll("\\(","\\( ").replaceAll("\\)", " \\)");
		//System.out.println(treeString);
		return treeString;
	}

	public static void main(String[] args) throws IOException{
		StanfordParserHandel st = new StanfordParserHandel();
		st.initializeParser();
		long start = System.currentTimeMillis();
		BufferedReader bf = new BufferedReader (new InputStreamReader(new FileInputStream("data/trainA.p_c_sep")));
		int total = 10000;
		String line;
		while ( (line = bf.readLine())!= null){
			String[] words = line.split("  *");
			total -= words.length;
			for (int i=0; i< words.length; i++){
				System.out.println(st.getParseFeature(words[i]));
				System.out.println(st.getHistoryLengthFeature());
			}
			if (total <0 ) break;
		}

		long finish = System.currentTimeMillis();
		System.out.println((finish-start));	
	}
}
